<template>
  <view>
    <view class="title-box">
      {{ title }}
    </view>
    <view style="margin: 30upx">
      写入的NFC数据：
      <view class="form-box">
        <view class="form-box-time"> ID: </view>
        <input class="form-box-input" type="text" v-model="id" />
      </view>
      <view class="form-box">
        <view class="form-box-time"> PAYLOAD: </view>
        <input class="form-box-input" type="text" v-model="payload" />
      </view>
      <view class="form-box">
        <view class="form-box-time"> TYPE: </view>
        <input class="form-box-input" type="text" v-model="type" />
      </view>
    </view>
    <view style="margin: 30upx">
      读取的NFC：
      <view class="form-box">
        <view class="form-box-time"> ID: </view>
        <view class="form-box-input">
          {{ read.id }}
        </view>
      </view>
      <view class="form-box">
        <view class="form-box-time"> PAYLOAD: </view>
        <view class="form-box-input">
          {{ read.payload }}
        </view>
      </view>
      <view class="form-box">
        <view class="form-box-time"> TYPE: </view>
        <view class="form-box-input">
          {{ read.type }}
        </view>
      </view>
      <view class="form-box">
        <view class="form-box-time"> AID: </view>
        <view class="form-box-input">
          {{ aid }}
        </view>
      </view>
    </view>
    <!-- 文本内容 -->
    <view style="margin: 30upx"> {{ content }} </view>
    <view class="fixed-btn" style="z-index: 1">
      <view class="my-button-primary" @click="initDevice">打开NFC</view>
      <view class="my-button-primary" @click="closeNFC">关闭NFC</view>
      <view v-if="isWrite" class="my-button-primary" @click="writeData">写入数据</view>
    </view>
  </view>
</template>

<script setup>
import { ab2hex, string2ArrayBuffer, byteToString } from "./index";
import { ref } from "vue";
const title = ref("NFC读写示例");
const isWrite = ref(false);
// 写入NFC的数据
const id = ref("");
const payload = ref("");
const type = ref("");

const content = ref("");
const read = ref({
  id: "",
  payload: "",
  type: "",
});

/**
 * 初始化 NFC 模块-获取实例
 */
const NFCAdapter = ref(null);
const tab = ref({});
const initDevice = () => {
  NFCAdapter.value = wx.getNFCAdapter();
  tab.value = {
    "ISO-DEP": NFCAdapter.value.getIsoDep(),
    "MIFARE Classic": NFCAdapter.value.getMifareClassic(),
    "MIFARE Ultraligh": NFCAdapter.value.getMifareUltralight(),
    NDEF: NFCAdapter.value.getNdef(),
    "NFC-A": NFCAdapter.value.getNfcA(),
    "NFC-B": NFCAdapter.value.getNfcB(),
    "NFC-F": NFCAdapter.value.getNfcF(),
    "NFC-V": NFCAdapter.value.getNfcV(),
  };

  // 开启监听
  NFClistener();
};

const aid = ref(null);
//  触发监听NFG事件
const NFClistener = () => {
  NFCAdapter.value.startDiscovery({
    success: (res) => {
      console.log("成功开启监听NFC事件");
      title.value = "请将设备放入识别区NFC";
    },
    fail: (error) => {
      title.value = "请刷新重试";
      console.error(error);
    },
  });

  // 监听 NFC 标签
  NFCAdapter.value.onDiscovered((callback) => {
    aid.value = ab2hex(callback.id);
    // 如果有数据，数据进行格式转换-并展示
    if (callback.messages) {
      let cordsArray = callback.messages[0].records;
      cordsArray.find((item) => {
        console.log(item);
        read.value.payload = byteToString(new Uint8Array(item.payload));
        read.value.id = byteToString(new Uint8Array(item.id));
        read.value.type = byteToString(new Uint8Array(item.type));
      });
    }

    if (callback.techs.length != 0) {
      title.value = "识别成功！";
      content.value = "可支持标签：";
      // 确定标签类型
      callback.techs.forEach((res, index) => {
        if (index != 0) {
          content.value += "、";
        }
        content.value += res;
        // 开启支持写入
        if (res == "NDEF") {
          console.log("开启支持写入");
          isWrite.value = true;
        }
      });
    } else {
      title.value = "无效设备";
      console.log("无效设备");
    }
  });
};

const NFCTab = ref(null);
/* 设备标签 */
const initTab = (item) => {
  NFCTab.value = tab.value[item];
  NFCTab.value.connect({
    success: (res) => {
      title.value = "连接设备成功";
      console.log(res);
    },
    fail: (error) => {
      title.value = "连接设备失败";
      console.error(error);
    },
  });
  return NFCTab.value;
};

/* 获取ATQA信息 */
const getAtqa = () => {
  NFCTab.value.getAtqa({
    success: (res) => {
      console.log(res);
    },
    fail: (error) => {
      console.error(error);
    },
    complete: (res) => {
      console.log(res);
    },
  });
};

/* 获取最大传输长度 */
const getMaxTransceiveLength = () => {
  NFCTab.value.getMaxTransceiveLength({
    success: (res) => {
      console.log(res);
    },
    fail: (error) => {
      console.error(error);
    },
    complete: (res) => {
      console.log(res);
    },
  });
};

/* 获取SAK信息 */
const getSak = () => {
  NFCTab.value.getSak({
    success: (res) => {
      console.log(res);
    },
    fail: (error) => {
      console.error(error);
    },
    complete: (res) => {
      console.log(res);
    },
  });
};

/**
 * 写入数据
 */
const writeData = async () => {
  // 获取初始化标签对象——连接设备
  NFCTab.value = await initTab("NDEF");
  // 写入的数据
  const records = [
    {
      id: string2ArrayBuffer(id.value),
      payload: string2ArrayBuffer(payload.value),
      type: string2ArrayBuffer(type.value),
      tnf: 2,
    },
  ];
  // 执行写入
  NFCTab.value.writeNdefMessage({
    records: records,
    success: (res) => {
      title.value = "数据写入成功";
      console.log(res);
    },
    fail: (error) => {
      title.value = "数据写入失败";
      console.error(error);
    },
    complete: (res) => {
      closeConnect(NFCTab.value);
      isWrite.value = false;
      title.value = "请将设备放入识别区NFC";
      console.log(res);
    },
  });
};

// 关闭 连接
const closeConnect = (NFCTab) => {
  NFCTab.close({
    success: (res) => {
      title.value = "清除标签连接成功";
      console.log("清除标签连接成功");
    },
    fail: (error) => {
      title.value = "清除标签连接失败";
      console.error("清除标签连接失败");
    },
    complete: (res) => {
      console.log(res);
    },
  });
};

/* 取消取消监听 NFC Tag */
const closeNFC = () => {
  NFCAdapter.value.offDiscovered((callback) => {});
  NFCAdapter.value.stopDiscovery();
};
</script>

<style lang="scss">
.title-box {
  height: 100upx;
  line-height: 100upx;
  padding-left: 30upx;
  text-align: start;
  border-bottom: 1upx solid #d1d1d1;
}
.fixed-btn {
  position: fixed;
  left: 0;
  bottom: 0;
  z-index: 99;
  width: 100%;
  padding: 24upx;
  box-sizing: border-box;
  background-color: #ffffff;
}
.my-button-primary {
  height: 80upx;
  background: linear-gradient(270deg, #5063b4 2%, #457fff 97%);
  border-radius: 8rpx;
  font-size: 34rpx;
  color: #ffffff;
  line-height: 80upx;
  margin: 10upx 0upx;
  text-align: center;
}
.my-button-primary:active {
  background: linear-gradient(270deg, #4b5eaa 2%, #427af4 97%);
}
.form-box {
  display: flex;
  justify-content: space-between;
  align-items: center;
  min-height: 80upx;

  .form-box-input {
    font-size: 28upx;
    flex: 1;
    margin-left: 30upx;
    color: #3e3e3e;
    text-align: start;
  }
  .form-box-time {
    font-size: 28upx;
    margin-left: 30upx;
    width: 200upx;
    color: #3e3e3e;
    text-align: start;
  }
}
</style>
